Skip to content

Array Iteration Methods

One of the novel things about React is that JSX doesn't include any iteration helpers.

In most templating languages, you have custom syntax like {{#each}} to help you iterate through a set of data. In frameworks like Angular and Vue, you have directives like v-for to manage iteration.

React doesn't provide any abstractions here, and so we'll rely on the built-in methods that are part of the JavaScript language, methods like map and filter.

If we can become comfortable with these core methods, we'll have a much easier time doing iteration in React. In this section, we'll learn about some of the most common and useful methods.

forEach

We use forEach when we want to perform some sort of action on every item in an array.

Here's an example:

const pizzaToppings = [
'cheese',
'avocado',
'halibut',
'custard',
];
pizzaToppings.forEach((topping) => {
console.log(topping);
});

In this example, we're logging the value of each topping, one at a time. Here's what the console output would be:

cheese
avocado
halibut
custard

The forEach method accepts a function as its argument. This is commonly known as a callback function.

The term “callback function” refers to a function that we pass to another function. In this case, we write an arrow function that looks like this:

(topping) => {
console.log(topping);
}

We don't call this function ourselves; instead, we pass it as an argument to the forEach method. The JavaScript engine will call this function for us, supplying the topping argument as it iterates over the array.

Accessing the index

The callback we pass to forEach takes a second optional parameter:

const pizzaToppings = [
'cheese',
'avocado',
'halibut',
'custard',
];
pizzaToppings.forEach((topping, index) => {
console.log(index, topping);
});

The index is the position in the array of the current item, starting from 0. This code would log:

0 cheese
1 avocado
2 halibut
3 custard

A common format

JavaScript gives us several tools for iterating over the items in an array. We could have used a for loop, and it's arguably much simpler. There are no complicated callback functions! So why should we learn about .forEach?

Here's the biggest advantage: forEach is part of a family of array iteration methods. Taken as a whole, this family allows us to do all sorts of amazing things, like finding a particular item in the array, filtering a list, and much more.

All of the methods in this family follow the same basic structure. For example, they all support the optional index parameter we just looked at!

Let's look at another member of this family: the filter method.

filter

Things start to get really interesting with filter.

Here's a quick example:

const students = [
{ name: 'Aisha', grade: 89 },
{ name: 'Bruno', grade: 55 },
{ name: 'Carlos', grade: 68 },
{ name: 'Dacian', grade: 71 },
{ name: 'Esther', grade: 40 },
];
const studentsWhoPassed = students.filter(student => {
return student.grade >= 60;
});
console.log(studentsWhoPassed);
/*
[
{ name: 'Aisha', grade: 89 },
{ name: 'Carlos', grade: 68 },
{ name: 'Dacian', grade: 71 },
]
*/

In many ways, filter is very similar to forEach. It takes a callback function, and that callback function will be called once per item in the array.

Unlike forEach, however, filter produces a value. Specifically, it produces a new array which contains a subset of items from the original array.

Typically, our callback function should return a boolean value, either true or false. The filter method calls this function once for every item in the array. If the callback returns true, this item is included in the new array. Otherwise, it's excluded.

Important to note: The filter method doesn't modify the original array. This is true for all of the array methods discussed in this lesson.

Here's one more example:

const nums = [5, 12, 15, 31, 40];
const evenNums = nums.filter(num => {
return num % 2 === 0;
});
console.log(nums); // Hasn't changed: [5, 12, 15, 31, 40]
console.log(evenNums); // [12, 40]

map

Finally, we have the map method. This is the most commonly-used array method, when working with React.

Let's start with an example:

const people = [
{ name: 'Aisha', grade: 89 },
{ name: 'Bruno', grade: 55 },
{ name: 'Carlos', grade: 68 },
{ name: 'Dacian', grade: 71 },
{ name: 'Esther', grade: 40 },
];
const screamedNames = people.map(person => {
return person.name.toUpperCase();
});
console.log(screamedNames);
/*
['AISHA', 'BRUNO', 'CARLOS', 'DACIAN', 'ESTHER']
*/

In many ways, map is quite a lot like forEach. We give it a callback function, and it iterates over the array, calling the function once for each item in the array.

Here's the big difference, though: map produces a brand new array, full of transformed values.

The forEach function will always return undefined:

const nums = [1, 2, 3];
const result = nums.forEach(num => num + 1);
console.log(result); // undefined

By contrast, map will "collect" all the values we return from our callback, and put them into a new array:

const nums = [1, 2, 3];
const result = nums.map(num => num + 1);
console.log(result); // [2, 3, 4]

Like filter, map doesn't mutate the original array; it produces a brand-new array.

Also, the new array will always have the exact same length as the original array. We can't "skip" certain items by returning false or not returning anything at all:

const people = [
{ id: 'a', name: 'Aisha' },
{ id: 'b' },
{ id: 'c' },
{ id: 'd', name: 'Dacian' },
{ id: 'e' },
];
const screamedNames = people.map(person => {
if (person.name) {
return person.name.toUpperCase();
}
});
console.log(screamedNames);
/*
['AISHA', undefined, undefined, 'DACIAN', undefined]
*/

Here's a helpful way to think about map: it's exactly like forEach, except it "saves" whatever we return from the callback into a new array.

Accessing the index

Like the other methods we've seen, we can pass a second parameter to access the current item's index:

const people = [
{ name: 'Aisha', grade: 89 },
{ name: 'Bruno', grade: 55 },
{ name: 'Carlos', grade: 68 },
{ name: 'Dacian', grade: 71 },
{ name: 'Esther', grade: 40 },
];
const numberedNames = people.map((person, index) => {
return `${index}-${person.name}`;
});
console.log(numberedNames);
/*
['0-Aisha', '1-Bruno', '2-Carlos', '3-Dacian', '4-Esther']
*/

Additional methods

We've seen 3 of the most common methods here, but there are actually several more that follow this same format, including find (selecting a single item from the array), every (checking if all items in an array fulfill some condition), and reduce (combine all items in the array into a single final value).

You can learn more about these methods on MDN.